<!--
 * @Description: 学生详情页面
 * @Author: charles
 * @Date: 2021-12-19 10:04:31
 * @LastEditors: charles
 * @LastEditTime: 2021-12-19 10:18:04
-->
<template>
  <div class="student-detail">
    <div class="detail-header">
      <el-button icon="el-icon-arrow-left" @click="backHandler">返回</el-button>
      <h2>学生详情</h2>
    </div>
    
    <!-- 错误提示 -->
    <el-alert
      v-if="fetchError"
      title="数据获取失败"
      type="error"
      description="获取学生信息失败，请稍后重试或联系管理员"
      show-icon
      :closable="false"
      style="margin-bottom: 20px"
    >
      <template slot="title">
        数据获取失败
        <el-button type="text" size="small" @click="retryFetchData">重试</el-button>
      </template>
    </el-alert>
    
    <!-- 学生基本信息 -->
    <el-card class="info-card" v-loading="loading">
      <div v-if="studentInfo">
        <div class="info-row">
          <el-row :gutter="20">
            <el-col :span="8">
              <span class="info-item">
                <span class="label">学号:</span>
                <span class="value">{{ studentInfo.id }}</span>
              </span>
            </el-col>
            <el-col :span="8">
              <span class="info-item">
                <span class="label">姓名:</span>
                <span class="value">{{ studentInfo.name }}</span>
              </span>
            </el-col>
            <el-col :span="8">
              <span class="info-item">
                <span class="label">性别:</span>
                <span class="value">{{ studentInfo.gender === 'M' ? '男' : '女' }}</span>
              </span>
            </el-col>
          </el-row>
        </div>
        
        <div class="info-row">
          <el-row :gutter="20">
            <el-col :span="8">
              <span class="info-item">
                <span class="label">年级:</span>
                <span class="value">{{ studentInfo.grade }}</span>
              </span>
            </el-col>
            <el-col :span="8">
              <span class="info-item">
                <span class="label">专业:</span>
                <span class="value">{{ studentInfo.major }}</span>
              </span>
            </el-col>
            <el-col :span="8">
              <span class="info-item">
                <span class="label">班级:</span>
                <span class="value">{{ studentInfo.className }}</span>
              </span>
            </el-col>
          </el-row>
        </div>
        
        <div class="info-row">
          <el-row :gutter="20">
            <el-col :span="8">
              <span class="info-item">
                <span class="label">邮箱:</span>
                <span class="value">{{ studentInfo.email }}</span>
              </span>
            </el-col>
            <el-col :span="8">
              <span class="info-item">
                <span class="label">已选课程数:</span>
                <span class="value">{{ selectedCourses.length }}</span>
              </span>
            </el-col>
            <el-col :span="8">
              <span class="info-item">
                <span class="label">总学分:</span>
                <span class="value">{{ totalCredits }}</span>
              </span>
            </el-col>
          </el-row>
        </div>
      </div>
      <div v-else-if="!loading && !fetchError" class="empty-tip">
        暂无学生信息
      </div>
    </el-card>
    
    <!-- 已选课程 -->
    <el-card class="info-card" v-loading="coursesLoading">
      <div slot="header" class="clearfix">
        <span>已选课程</span>
        <el-button style="float: right; padding: 3px 0; margin-left: 10px;" 
                  type="text" 
                  icon="el-icon-plus" 
                  @click="openCourseSelection"
                  :disabled="!studentInfo">选课</el-button>
      </div>
      
      <el-alert
        v-if="coursesError"
        title="获取课程数据失败"
        type="warning"
        description="获取已选课程失败，请稍后重试"
        show-icon
        :closable="true"
        style="margin-bottom: 15px"
        @close="coursesError = false"
      >
        <template slot="title">
          获取课程数据失败
          <el-button type="text" size="small" @click="retryFetchCourses">重试</el-button>
        </template>
      </el-alert>
      
      <el-table 
        v-if="!coursesError || selectedCourses.length > 0" 
        :data="selectedCourses" 
        border 
        stripe 
        style="width: 100%" 
        :empty-text="coursesEmptyText">
        <el-table-column prop="courseId" label="课程编号" width="120" align="center"></el-table-column>
        <el-table-column prop="courseName" label="课程名称"></el-table-column>
        <el-table-column prop="credit" label="学分" width="80" align="center"></el-table-column>
        <el-table-column prop="teacherName" label="任课教师" width="120" align="center"></el-table-column>
        <el-table-column prop="selectTime" label="选课时间" width="160" align="center"></el-table-column>
        <el-table-column label="操作" width="120" align="center">
          <template slot-scope="scope">
            <el-button type="text" size="small" style="color: #F56C6C" @click="handleCancelCourse(scope.row)">退选</el-button>
          </template>
        </el-table-column>
      </el-table>
    </el-card>
    
    <!-- 选课对话框 -->
    <el-dialog title="选择课程" :visible.sync="selectionDialogVisible" width="800px">
      <div class="filter-bar">
        <el-input 
          v-model="searchKeyword" 
          placeholder="请输入课程名称或编号" 
          style="width: 220px; margin-right: 10px;"
          clearable
          prefix-icon="el-icon-search"
          @keyup.enter.native="searchCourses">
        </el-input>
        <el-button type="primary" @click="searchCourses">搜索</el-button>
      </div>
      
      <el-alert
        v-if="availableCoursesError"
        title="获取可选课程失败"
        type="warning"
        description="获取可选课程数据失败，请稍后重试"
        show-icon
        :closable="true"
        style="margin-bottom: 15px"
        @close="availableCoursesError = false"
      >
        <template slot="title">
          获取可选课程失败
          <el-button type="text" size="small" @click="fetchAvailableCourses">重试</el-button>
        </template>
      </el-alert>
      
      <el-table 
        v-loading="availableCoursesLoading" 
        :data="availableCourses" 
        border 
        style="width: 100%"
        :empty-text="availableCoursesEmptyText">
        <el-table-column prop="courseId" label="课程编号" width="120" align="center"></el-table-column>
        <el-table-column prop="courseName" label="课程名称"></el-table-column>
        <el-table-column prop="credit" label="学分" width="80" align="center"></el-table-column>
        <el-table-column prop="teacherName" label="任课教师" width="120" align="center"></el-table-column>
        <el-table-column label="已选/容量" width="100" align="center">
          <template slot-scope="scope">
            {{ scope.row.selectedCount }}/{{ scope.row.capacity }}
          </template>
        </el-table-column>
        <el-table-column prop="status" label="状态" width="80" align="center">
          <template slot-scope="scope">
            <el-tag :type="scope.row.status === '可选' ? 'success' : 'danger'" size="small">
              {{ scope.row.status }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column label="操作" width="80" align="center">
          <template slot-scope="scope">
            <el-button 
              type="text" 
              size="small" 
              :disabled="isAlreadySelected(scope.row.courseId) || scope.row.status === '已满'"
              @click="handleSelectCourse(scope.row)">
              选课
            </el-button>
          </template>
        </el-table-column>
      </el-table>
    </el-dialog>
  </div>
</template>

<script>
import { getStudentDetail, getStudentCourses, selectCourse, cancelCourse, getAvailableCourses } from '@/api/student'

export default {
  data() {
    return {
      studentId: '',
      loading: false,
      fetchError: false,
      studentInfo: null,
      
      // 已选课程相关
      selectedCourses: [],
      coursesLoading: false,
      coursesError: false,
      
      // 课程选择相关
      availableCourses: [],
      availableCoursesLoading: false,
      availableCoursesError: false,
      selectionDialogVisible: false,
      searchKeyword: ''
    }
  },
  computed: {
    // 计算总学分
    totalCredits() {
      return this.selectedCourses.reduce((total, course) => total + (parseFloat(course.credit) || 0), 0)
    },
    
    // 已选课程空文本提示
    coursesEmptyText() {
      if (this.coursesLoading) return '加载中...'
      return this.coursesError ? '加载失败，请重试' : '暂无已选课程'
    },
    
    // 可选课程空文本提示
    availableCoursesEmptyText() {
      if (this.availableCoursesLoading) return '加载中...'
      if (this.availableCoursesError) return '获取课程失败，请重试'
      if (this.searchKeyword) return '没有符合条件的课程'
      return '暂无可选课程'
    }
  },
  mounted() {
    this.studentId = this.$route.query.id
    if (this.studentId) {
      this.fetchData()
    } else {
      this.$message.error('学生ID不能为空')
      this.backHandler()
    }
  },
  methods: {
    // 返回上一页
    backHandler() {
      this.$router.go(-1)
    },
    
    // 获取所有数据
    fetchData() {
      this.fetchStudentInfo()
      this.fetchSelectedCourses()
    },
    
    // 重试加载
    retryFetchData() {
      this.fetchError = false
      this.fetchData()
    },
    
    // 重试加载课程
    retryFetchCourses() {
      this.coursesError = false
      this.fetchSelectedCourses()
    },
    
    // 获取学生信息
    async fetchStudentInfo() {
      this.loading = true
      this.fetchError = false
      
      try {
        const res = await getStudentDetail(this.studentId)
        if (res && res.status === 200 && res.data) {
          this.studentInfo = res.data
        } else {
          this.studentInfo = null
          this.fetchError = true
          this.$message.error(res.message || '获取学生信息失败')
        }
      } catch (error) {
        console.error('获取学生信息失败:', error)
        this.studentInfo = null
        this.fetchError = true
      } finally {
        this.loading = false
      }
    },
    
    // 获取已选课程
    async fetchSelectedCourses() {
      if (!this.studentId) return
      
      this.coursesLoading = true
      this.coursesError = false
      
      try {
        const res = await getStudentCourses(this.studentId)
        if (res && res.status === 200) {
          this.selectedCourses = res.data || []
        } else {
          this.selectedCourses = []
          this.coursesError = true
        }
      } catch (error) {
        console.error('获取已选课程失败:', error)
        this.selectedCourses = []
        this.coursesError = true
      } finally {
        this.coursesLoading = false
      }
    },
    
    // 打开选课对话框
    openCourseSelection() {
      this.selectionDialogVisible = true
      this.searchKeyword = ''
      this.fetchAvailableCourses()
    },
    
    // 获取可选课程
    async fetchAvailableCourses() {
      this.availableCoursesLoading = true
      this.availableCoursesError = false
      
      try {
        const params = {
          keyword: this.searchKeyword
        }
        const res = await getAvailableCourses(params)
        if (res && res.status === 200) {
          this.availableCourses = res.data || []
        } else {
          this.availableCourses = []
          this.availableCoursesError = true
          this.$message.error(res.message || '获取可选课程失败')
        }
      } catch (error) {
        console.error('获取可选课程失败:', error)
        this.availableCourses = []
        this.availableCoursesError = true
      } finally {
        this.availableCoursesLoading = false
      }
    },
    
    // 搜索课程
    searchCourses() {
      this.fetchAvailableCourses()
    },
    
    // 检查课程是否已选
    isAlreadySelected(courseId) {
      return this.selectedCourses.some(course => course.courseId === courseId)
    },
    
    // 选课
    async handleSelectCourse(course) {
      // 判断是否已选择该课程
      if (this.isAlreadySelected(course.courseId)) {
        this.$message.warning('已选择该课程')
        return
      }
      
      // 判断课程是否已满
      if (course.status === '已满') {
        this.$message.warning('该课程已满')
        return
      }
      
      try {
        const reqData = {
          studentId: this.studentId,
          courseId: course.courseId
        }
        const res = await selectCourse(reqData)
        if (res && res.status === 200) {
          this.$message.success('选课成功')
          // 刷新已选课程
          this.fetchSelectedCourses()
          // 关闭对话框
          this.selectionDialogVisible = false
        } else {
          this.$message.error(res.message || '选课失败')
        }
      } catch (error) {
        console.error('选课失败:', error)
        this.$message.error('选课失败，请稍后重试')
      }
    },
    
    // 退选课程
    handleCancelCourse(course) {
      this.$confirm('确定要退选该课程吗？', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(async () => {
        try {
          const reqData = {
            studentId: this.studentId,
            courseId: course.courseId
          }
          const res = await cancelCourse(reqData)
          if (res && res.status === 200) {
            this.$message.success('退选成功')
            // 刷新已选课程列表
            this.fetchSelectedCourses()
          } else {
            this.$message.error(res.message || '退选失败')
          }
        } catch (error) {
          console.error('退选课程失败:', error)
          this.$message.error('退选课程失败，请稍后重试')
        }
      }).catch(() => {})
    }
  }
}
</script>

<style lang="scss" scoped>
.student-detail {
  padding: 20px;
}

.detail-header {
  display: flex;
  align-items: center;
  margin-bottom: 20px;
  
  h2 {
    margin: 0 0 0 20px;
    font-size: 18px;
    font-weight: bold;
  }
}

.info-card {
  margin-bottom: 20px;
}

.info-row {
  margin-bottom: 15px;
  
  &:last-child {
    margin-bottom: 0;
  }
}

.info-item {
  .label {
    color: #606266;
    font-weight: bold;
    margin-right: 5px;
  }
  
  .value {
    color: #303133;
  }
}

.empty-tip {
  text-align: center;
  color: #909399;
  padding: 30px 0;
}

.filter-bar {
  margin-bottom: 10px;
}
</style>